<?php

namespace Respect\StackedViewRenderer;

use \DirectoryIterator;
use \UnexpectedValueException;

class ViewItem
{

    protected $file;
    protected $child = null;
    protected $render = null;
    protected $data = array();

    public function __construct($file, $data, $contentHandler)
    {
        $extension = $contentHandler->negotiateExtension($this->getViews(dirname($file)));
        $this->file = $this->getAbsolutePath(
                $file . '.' . $extension . '.php'
        );
        $this->data = $data;
    }

    protected function getViews($file)
    {
        $available = array();
        try {
            $dir = new DirectoryIterator($this->getAbsolutePath($file));
            foreach ($dir as $view) {
                if (!$view->isFile())
                    continue;
                $fileParts = explode('.', $view->getFileName());
                if (count($fileParts) != 3)
                    continue;
                $available[] = $fileParts[1];
            }
        } catch (UnexpectedValueException $e) {

        }
        return $available;
    }

    protected function renderScript($file, array $compactVariables)
    {
        ob_start();
        extract($compactVariables);
        $returnValue = include $file;
        if ($returnValue !== 1) {
            ob_end_clean();
            return $returnValue;
        }
        return ob_get_clean();
    }

    protected function getAbsolutePath($filePath)
    {
        $lookupPaths = explode(PATH_SEPARATOR, get_include_path());
        foreach ($lookupPaths as $baseDir) {
            $file = $baseDir . $filePath;
            if (file_exists($file))
                return $file;
        }
        return false;
    }

    public function render()
    {
        if (!empty($this->render))
            return $this->render;
        if (file_exists($this->file)) {
            $this->render = trim($this->renderScript(
                        $this->file,
                        array(
                            'data' => $this->data,
                            'bottom' => $this->bottom,
                            'child' => $this->child
                        )
                ));
        }
        if (empty($this->render)) {
            if ($this->child) {
                $this->render = $this->child->render();
            } else {
                ob_start();
                var_dump($this->data->getArrayCopy());
                $this->render = ob_get_clean();
            }
        }
        return $this->render;
    }

    public function setBottom(ViewItem $bottom)
    {
        $this->bottom = $bottom;
    }

    public function setChild(ViewItem $child)
    {
        $this->child = $child;
    }

}